package com.liuyu.common.framework.lang;

import com.google.gson.Gson;
import org.springframework.cglib.beans.BeanCopier;

import java.io.*;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @ClassName BeanCoperUtil
 * @Author: liuyu
 * @Date: Created in 2021/4/25 9:15
 * @Version: 1
 * @Modified By:
 */
public class BeanCopyUtil {
    public static final Map<String, BeanCopier> BEAN_COPIER_MAP = new ConcurrentHashMap<>();
    public static final Gson GSON = new Gson();


    /**
     * 深度复制list对象,先序列化对象，再反序列化对象
     *
     * @param src 需要复制的对象列表
     * @return 返回新的对象列表
     * @throws IOException            读取Object流信息失败
     * @throws ClassNotFoundException 泛型类不存在
     */
    public static <T> List<T> deepCopyByStream(List<T> src)
            throws IOException, ClassNotFoundException {
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(byteOut);
        out.writeObject(src);
        ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
        ObjectInputStream in = new ObjectInputStream(byteIn);
        return (List<T>) in.readObject();
    }

    /**
     * 深度复制list对象,先序列化对象，再反序列化对象
     *
     * @param src 需要复制的对象列表
     * @return 返回新的对象列表
     * @throws IOException            读取Object流信息失败
     * @throws ClassNotFoundException 泛型类不存在
     */
    public static Object deepCopyByGson(Object src) {
        String json = GSON.toJson(src);
        Object obj = GSON.fromJson(json, src.getClass());
        return obj;
    }


    /**
     * BeanCopier的copy
     * @param source 源文件的
     * @param target 目标文件
     */
    public static void weakCopyByBeanCopier(Object source, Object target) {
        String key = genKey(source.getClass(), target.getClass());
        BeanCopier beanCopier;
        if (BEAN_COPIER_MAP.containsKey(key)) {
            beanCopier = BEAN_COPIER_MAP.get(key);
        } else {
            beanCopier = BeanCopier.create(source.getClass(), target.getClass(), false);
            BEAN_COPIER_MAP.put(key, beanCopier);
        }
        beanCopier.copy(source, target, null);
    }

    /**
     * 生成key
     * @param srcClazz 源文件的class
     * @param tgtClazz 目标文件的class
     * @return string
     */
    private static String genKey(Class<?> srcClazz, Class<?> tgtClazz) {
        return srcClazz.getName() + tgtClazz.getName();
    }
}
